#include "../../../Include/Core/Archive/WizArchive.hpp"

#include "../../../Include/Core/Accessor/WizAccessor.hpp"

#include "./WizArchiveInput.hpp"
#include "./WizArchiveOutput.hpp"

namespace Wiz
{
    namespace Archive
    {
        ::Wiz::Archive::Ptr CreateOutput(::Wiz::Accessor::Ptr APtr)
        {
            return new ::Wiz::Archive::Output::Type(APtr);
        }
        ::Wiz::Archive::Ptr CreateInput(::Wiz::Accessor::Ptr APtr)
        {
            return new ::Wiz::Archive::Input::Type(APtr);
        }

        ::Wiz::Archive::Ptr Create(
            ::Wiz::Archive::Category::In InCat, ::Wiz::Endian::In InEndian, ::Wiz::File::Ptr InFPtr
            )
        {
            ::Wiz::Accessor::Ptr AP = ::Wiz::Accessor::Create(InFPtr);
            if (::Wiz::NotValidPtr(AP))
            {
                return WIZ_NULLPTR;
            }
            if (AP->SwitchEndian(InEndian))
            {
                ::Wiz::Archive::Ptr ArchivePtr = WIZ_NULLPTR;

                if (InCat == ::Wiz::Archive::Category::eInput)
                {
                    ArchivePtr = new ::Wiz::Archive::Input::Type(AP);
                }
                else if (InCat == ::Wiz::Archive::Category::eOutput)
                {
                    ArchivePtr = new ::Wiz::Archive::Output::Type(AP);
                }

                if (::Wiz::IsValidPtr(ArchivePtr))
                {
                    return ArchivePtr;
                }
            }

            ::Wiz::Accessor::Destory(AP);
            return WIZ_NULLPTR;
        }

        ::Wiz::Archive::Ptr Create(
            ::Wiz::Archive::Category::In InCat, ::Wiz::Endian::In InEndian, ::Wiz::ByteBuffer::Ref FBRef
            )
        {
            ::Wiz::Accessor::Ptr AP = ::Wiz::Accessor::Create(FBRef);
            if (::Wiz::NotValidPtr(AP))
            {
                return WIZ_NULLPTR;
            }
            if (AP->SwitchEndian(InEndian))
            {
                ::Wiz::Archive::Ptr ArchivePtr = WIZ_NULLPTR;

                if (InCat == ::Wiz::Archive::Category::eInput)
                {
                    ArchivePtr = new ::Wiz::Archive::Input::Type(AP);
                }
                else if (InCat == ::Wiz::Archive::Category::eOutput)
                {
                    ArchivePtr = new ::Wiz::Archive::Output::Type(AP);
                }

                if (::Wiz::IsValidPtr(ArchivePtr))
                {
                    return ArchivePtr;
                }
            }

            ::Wiz::Accessor::Destory(AP);
            return WIZ_NULLPTR;
        }

        ::Wiz::Void::Type   Destory(::Wiz::Archive::Ptr ArchivePtr)
        {
            delete ArchivePtr; 
        }
    } /// end of namespace Archive
} /// end of namespace Wiz

